import fs from 'fs'
import path from 'path'

import { parse, stringify } from 'yaml'

import { checkE2ETasks, taskGroups } from './e2e-task-group'
import { log } from './utils'

const E2E_PATH = path.resolve(__dirname, '../tools/cli', 'e2e.ci.yaml')

const CI_PATH = path.resolve(__dirname, '../', '.codebase/pipelines/ci.yaml')

// 在 id 上标记这个 ci job 为该文件生成的
const E2E_SYMBOL = 'auto_e2e'
// 占位符
const E2E_TASK_NAME = '${e2e-task-name}'

type TemplateLike = {
  steps: { name: string; commands: string[] }[]
  name: string
}

type CiLike = {
  jobs: Record<string, TemplateLike>
}

export function generateCi() {
  if (!checkE2ETasks(taskGroups)) {
    process.exit(1)
  }
  const e2eYaml = fs.readFileSync(E2E_PATH, 'utf8')
  const ciYaml = fs.readFileSync(CI_PATH, 'utf-8')
  const ci = parse(ciYaml) as CiLike
  const e2eTemplate = parse(e2eYaml) as TemplateLike

  delLastE2ETemplate(ci)

  const templates = getCiTemplates(e2eTemplate).reduce((res, template) => ({ ...res, ...template }))
  ci.jobs = { ...ci.jobs, ...templates }
  writeCi(ci)
}

function delLastE2ETemplate(ci: CiLike) {
  Object.entries(ci.jobs).forEach(([taskId, template]) => {
    if (template.name && template.name.startsWith(E2E_SYMBOL)) {
      delete ci.jobs[taskId]
    }
  })
}

function getCiTemplates(template: TemplateLike): Record<string, TemplateLike>[] {
  return Object.entries(taskGroups).map(([taskId, { name }]) => {
    const _template = JSON.parse(JSON.stringify(template)) as TemplateLike
    const e2eIndex = _template.steps.findIndex((step) => step.name === 'e2e')
    _template.steps[e2eIndex].commands[1] = _template.steps[e2eIndex].commands[1].replace(E2E_TASK_NAME, taskId)
    _template.name = _template.name.replace(E2E_TASK_NAME, name || taskId)
    log('success', 'generate ci jobs', taskId)
    return { [taskId]: _template }
  })
}

function writeCi(ci: CiLike) {
  const ciYaml = stringify(ci)
  fs.writeFileSync(CI_PATH, ciYaml)
}
